package com.study.jdk.j8;

import org.junit.Test;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

/**
 * @author: jzhou
 * @date: 2024/11/28-22:31
 * @version: 1.0
 * @description: juc-study
 * Java 8日期时间API核心类
 */
public class DateTimeStudy {

    /**
     * LocalDate、LocalTime和LocalDateTime
     */
    @Test
    public void test1() {
        // 创建日期对象
        LocalDate date = LocalDate.now();
        // 获取当前日期
        System.out.println("当前日期：" + date);
        // 创建时间对象
        LocalTime time = LocalTime.now();
        // 获取当前时间
        System.out.println("当前时间：" + time);
        // 创建日期时间对象
        LocalDateTime dateTime = LocalDateTime.now();
        // 获取当前日期时间
        System.out.println("当前日期时间：" + dateTime);
        // 使用of方法创建指定日期时间
        LocalDate customDate = LocalDate.of(2024, 3, 18);
        LocalTime customTime = LocalTime.of(14, 30, 0);
        LocalDateTime customDateTime = LocalDateTime.of(2024, 3, 18, 14, 30, 0);
        System.out.println("自定义日期：" + customDate);
        System.out.println("自定义时间：" + customTime);
        System.out.println("自定义日期时间：" + customDateTime);
    }

    /**
     * Instant表示时间线上的一个瞬时点，常用于记录时间戳：
     * Duration
     */
    @Test
    public void test2() throws InterruptedException {
        // 获取当前时间戳
        Instant now = Instant.now();
        System.out.println("当前时间戳：" + now);
        // 获取1970年1月1日0时0分0秒到当前时间之间的毫秒数
        long millis = now.toEpochMilli();
        System.out.println("当前时间戳（毫秒数）：" + millis);
        // 从毫秒数创建Instant
        Instant instantFromEpochMilli = Instant.ofEpochMilli(System.currentTimeMillis());
        System.out.println("从1970年开始的秒数：" + instantFromEpochMilli);
        // 获取秒数
        long epochSecond = now.getEpochSecond();
        System.out.println("从1970年开始的秒数：" + epochSecond);
        //duration
        long duration = ChronoUnit.SECONDS.between(now, instantFromEpochMilli);
        Thread.sleep(1000);
        Instant stopWrite = Instant.now();
        Duration writeDuration = Duration.between(now, stopWrite);
        System.out.println("程序运行时长：" + writeDuration.toMillis() + "毫秒");
    }

    /**
     * 日期加减操作
     * 日期时间比较
     */
    @Test
    public void test3() {
        LocalDate today = LocalDate.now();
        // 日期加减
        LocalDate tomorrow = today.plusDays(1);
        LocalDate nextWeek = today.plusWeeks(1);
        LocalDate nextMonth = today.plusMonths(1);
        LocalDate nextYear = today.plusYears(1);
        // 使用minus进行日期减法
        LocalDate yesterday = today.minusDays(1);
        // 使用ChronoUnit进行更灵活的时间单位计算
        LocalDate nextFiveYears = today.plus(5, ChronoUnit.YEARS);
        System.out.println("今天：" + today);
        System.out.println("明天：" + tomorrow);
        System.out.println("下周：" + nextWeek);
        System.out.println("下个月：" + nextMonth);
        System.out.println("明年：" + nextYear);

        // 比较两个日期
        System.out.println(today.isBefore(tomorrow));  // true
        System.out.println(tomorrow.isAfter(nextWeek));    // false
        System.out.println(tomorrow.isEqual(nextYear));    // false
        // 计算日期间隔
        Period period = Period.between(tomorrow, nextMonth);
        System.out.println("相差天数：" + period.getDays());
        // 计算具体时间间隔
        LocalDateTime dateTime1 = LocalDateTime.of(2024, 3, 18, 10, 0);
        LocalDateTime dateTime2 = LocalDateTime.of(2024, 3, 18, 11, 30);
        Duration duration = Duration.between(dateTime1, dateTime2);
        System.out.println("相差分钟：" + duration.toMinutes());
    }

    /**
     * 日期格式化与解析 使用DateTimeFormatter
     */

    @Test
    public void test4() {
        LocalDateTime now = LocalDateTime.now();

        // 使用预定义的格式化器
        String basic = now.format(DateTimeFormatter.BASIC_ISO_DATE);
        String iso = now.format(DateTimeFormatter.ISO_DATE_TIME);

        // 自定义格式化模式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        String customFormat = now.format(formatter);

        System.out.println("基本格式：" + basic);
        System.out.println("ISO格式：" + iso);
        System.out.println("自定义格式：" + customFormat);

        // 解析日期字符串
        String dateStr = "2024年03月18日 14:30:00";
        LocalDateTime parsedDate = LocalDateTime.parse(dateStr, formatter);
        System.out.println("解析后的日期：" + parsedDate);
    }

    /**
     * 时区处理 ZonedDateTime的使用
     */
    @Test
    public void test5() {
        // 获取所有可用时区
        ZoneId.getAvailableZoneIds().forEach(System.out::println);

        // 创建特定时区的日期时间
        ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
        ZonedDateTime newYorkTime = ZonedDateTime.now(ZoneId.of("America/New_York"));

        System.out.println("东京时间：" + tokyoTime);
        System.out.println("纽约时间：" + newYorkTime);

        // 时区转换
        ZonedDateTime converted = tokyoTime.withZoneSameInstant(ZoneId.of("America/New_York"));
        System.out.println("转换后的纽约时间：" + converted);
    }
}
